package com.toidep.widgets.sectionlist;

import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;

import com.toidep.bitmaputil.ImageFetcher;

public abstract class AmazingAdapter extends BaseAdapter implements SectionIndexer, OnScrollListener {
	public static final String TAG = AmazingAdapter.class.getSimpleName();
	public AmazingListView amazingListView;
	public int sectionSize;
	public int firstItem;

	public boolean isStop;

	public boolean isLoadingMore;

	public ImageFetcher imageFetcher;

	public interface HasMorePagesListener {
		void noMorePages();

		void mayHaveMorePages();
	}

	/**
	 * The <em>current</em> page, not the page that is going to be loaded.
	 */
	public int page = 1;
	public int initialPage = 1;
	boolean automaticNextPageLoading = false;
	HasMorePagesListener hasMorePagesListener;

	public void setHasMorePagesListener(HasMorePagesListener hasMorePagesListener) {
		this.hasMorePagesListener = hasMorePagesListener;
	}

	public void setAmazingListView(AmazingListView amazingListView, int pageSize) {
		this.amazingListView = amazingListView;
		notifyMayHaveMorePages();
	}

	public void setSectionSize(int size) {
		sectionSize = size;
	}

	public void setImageFetcher(ImageFetcher imageFetcher) {
		this.imageFetcher = imageFetcher;
	}

	/**
	 * Pinned header state: don't show the header.
	 */
	public static final int PINNED_HEADER_GONE = 0;

	/**
	 * Pinned header state: show the header at the top of the list.
	 */
	public static final int PINNED_HEADER_VISIBLE = 1;

	/**
	 * Pinned header state: show the header. If the header extends beyond the
	 * bottom of the first shown element, push it up and clip.
	 */
	public static final int PINNED_HEADER_PUSHED_UP = 2;

	/**
	 * Computes the desired state of the pinned header for the given position of
	 * the first visible list item. Allowed return values are
	 * {@link #PINNED_HEADER_GONE}, {@link #PINNED_HEADER_VISIBLE} or
	 * {@link #PINNED_HEADER_PUSHED_UP}.
	 */
	public int getPinnedHeaderState(int position) {
		if (position <= 0 || getCount() == 0) {
			return PINNED_HEADER_GONE;
		}

		// The header should get pushed up if the top item shown
		// is the last item in a section for a particular letter.
		// int section = getSectionForPosition(position + 1);
		// Log.e("Section", "" + section);
		// int nextSectionPosition = getPositionForSection(section + 1);
		// if (nextSectionPosition != -1 && position == nextSectionPosition - 1)
		// {
		// return PINNED_HEADER_PUSHED_UP;
		// }
//		if (position % sectionSize == 0) {
//			return PINNED_HEADER_PUSHED_UP;
//		}
		if (position % sectionSize == 0) {
			return PINNED_HEADER_PUSHED_UP;
		}

		return PINNED_HEADER_VISIBLE;
	}

	/**
	 * Sets the initial page when {@link #resetPage()} is called. Default is 1
	 * (for APIs with 1-based page number).
	 */
	public void setInitialPage(int initialPage) {
		this.initialPage = initialPage;
	}

	/**
	 * Resets the current page to the page specified in
	 * {@link #setInitialPage(int)}.
	 */
	public void resetPage() {
		this.page = this.initialPage;
	}

	/**
	 * Increases the current page number.
	 */
	public void nextPage() {
		this.page++;
	}

	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		if (view instanceof AmazingListView) {
			((AmazingListView) view).configureHeaderView(firstVisibleItem);
		}
		firstItem = firstVisibleItem;
	}

	public void doWhenStopScroll(int firstItem, int totalItem) {

	}

	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
		} else {
		}
	}

	public final View getView(int position, View convertView, ViewGroup parent) {
		View res = getAmazingView(position, convertView, parent);

		if (position == getCount() - 1 && automaticNextPageLoading) {
			if (!isLoadingMore) {
				isLoadingMore = true;
				onNextPageRequested(page + 1);
			}
		}

		final int section = getSectionForPosition(position);
		boolean displaySectionHeaders = (getPositionForSection(section) == position);

		bindSectionHeader(res, position, displaySectionHeaders);
		return res;

	}

	public void notifyNoMorePages() {
		automaticNextPageLoading = false;
		if (hasMorePagesListener != null)
			hasMorePagesListener.noMorePages();
	}

	public void notifyMayHaveMorePages() {
		automaticNextPageLoading = true;
		if (hasMorePagesListener != null)
			hasMorePagesListener.mayHaveMorePages();
	}

	/**
	 * The last item on the lis is requested to be seen, so do the request and
	 * call {@link AmazingListView#tellNoMoreData()} if there is no more pages.
	 * 
	 * @param page
	 *            the page number to load.
	 */
	protected abstract void onNextPageRequested(int page);

	/**
	 * Configure the view (a listview item) to display headers or not based on
	 * displaySectionHeader (e.g. if displaySectionHeader
	 * header.setVisibility(VISIBLE) else header.setVisibility(GONE)).
	 */
	protected abstract void bindSectionHeader(View view, int position, boolean displaySectionHeader);

	/**
	 * read: get view too
	 */
	public abstract View getAmazingView(int position, View convertView, ViewGroup parent);

	/**
	 * Configures the pinned header view to match the first visible list item.
	 * 
	 * @param header
	 *            pinned header view.
	 * @param position
	 *            position of the first visible list item.
	 * @param alpha
	 *            fading of the header view, between 0 and 255.
	 */
	public abstract void configurePinnedHeader(View header, int position, int alpha);

	public abstract int getPositionForSection(int section);

	public abstract int getSectionForPosition(int position);

	public abstract int getSectionPosition(int position);

	public abstract Object[] getSections();
}
